<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <!-- 
    1. JS中用来存储待执行回调函数的队列包含2个不同特定的列队
      `宏队列`:用来保存待执行的宏任务(回调),比如:`定时器`回调/ajax回调/dom事件回调
      `微队列`:用来保存待执行的微任务(回调),比如:`Promise`的回调/muntation回调

    2. JS执行时会区别这2个队列:
      - JS执行引擎首先必须执行所有主线程的`初始化同步任务`代码
      - 然后每次准备取出第一个`宏任务执行前`,都要将所有的`微任务`一个一个取出来执行
      - **同步任务** -> **微任务** -> **宏任务**
   -->
  <img src="Promise系统学习_宏任务微任务原理图.png" alt="Promise系统学习_宏任务微任务原理图">

  <script>
    // 先指定回调函数再改变状态（常用）
    new Promise((resolve, reject) => {
      setTimeout(() => {
        //因为改变状态是异步的，整个异步回调被放入 宏队列 中。
        // 执行此处时，回调函数是在Promise实例身上，状态改变后，回调函数立即推到 微队列中
        resolve('成功的value11');
      }, 1000);
    }).then(  //执行到这行代码时，promise状态没有改变，不知道是成功还是失败，所以回调函数被放到Promise实例身上（一个伪数组按顺序存放），而不是微队列中
      (value) => { console.log('成功的value：' + value); },
      (reason) => { console.log('失败原因：' + reason); }
    );

    //先改变状态，在指定回调函数
    const promise = new Promise((resolve, reject) => {
      resolve('成功的value22');   //改变状态是同步的，在主线程中立即执行
    })
    //此时状态已经改变等待调用回调，
    // 回调函数就不会放到Promise实例身上，而是被推到 微队列 中排队，等待主线程忙完，之后按顺序依次取出微队列到主线程执行
    promise.then(
      (value) => { console.log('成功的value：' + value); },
      (reason) => { console.log('失败原因：' + reason); }
    )

    /*
      上面代码输出结果：
        成功的value：成功的value22
        成功的value：成功的value11
    */
  </script>
</body>

</html>